package apiexample.transform.datastructure;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import pku.sei.codesnippet.CodeSnippet;
import pku.sei.javasrcfile.JavaFileParser;
import pku.sei.javasrcfile.JavaMethodDecl;
import pku.sei.javasrcfile.JavaTypeDeclaration;

import com.apiexample.server.entity.DescriptionEntity;
import com.apiexample.server.entity.ExampleClassRelation;
import com.apiexample.server.entity.ExampleEntity;
import com.apiexample.server.entity.ExampleMethodRelation;

public class UsageExample {
	public int pageIndx;
	private ExampleEntity entity;
	public ExampleEntity getEntity() {
		return entity;
	}
	public void setEntity(ExampleEntity entity) {
		this.entity = entity;
	}
	private ArrayList<DescriptionEntity> precedingDes = new ArrayList<DescriptionEntity>();
	private ArrayList<DescriptionEntity> followingDes = new ArrayList<DescriptionEntity>();
	
	private CodeSnippet snippet;
	
	public ArrayList<ExampleMethodRelation> exampleMethodRelations = new ArrayList<ExampleMethodRelation>();
	public ArrayList<ExampleClassRelation> exampleClassRelations = new ArrayList<ExampleClassRelation>();
	/*
	 * the name of elements declared by the code snippet, such as class name (FQN and simple), method name, field name
	 */
	public HashSet<String> declaredMethodNames = new HashSet<String>();
	
	public HashSet<String> declaredTypeNames = new HashSet<String>();
	
	/*
	 * the name of elements references by the code snippet, such as class name (FQN and simple), method name (simple name), field name
	 */
	public HashSet<String> referencedMethodNames = new HashSet<String>();
	
	public HashSet<String> referencedTypeNames = new HashSet<String>();
	
	/*
	 * names of actual parameters of methods invoked by this example  
	 */
	public HashSet<String> actualArgs = new HashSet<String>();
	
	public CodeSnippet getSnippet() {
		return snippet;
	}
	public void setSnippet(CodeSnippet snippet) {
		this.snippet = snippet;
	}
	public ArrayList<DescriptionEntity> getPrecedingDes() {
		return precedingDes;
	}
	public void setPrecedingDes(ArrayList<DescriptionEntity> precedingDes) {
		this.precedingDes = precedingDes;
	}
	public ArrayList<DescriptionEntity> getFollowingDes() {
		return followingDes;
	}
	public void setFollowingDes(ArrayList<DescriptionEntity> followingDes) {
		this.followingDes = followingDes;
	}
	public void addPrecedingDes(DescriptionEntity des){
		precedingDes.add(des);
	}
	public void addFollowingDes(DescriptionEntity des){
		followingDes.add(des);
	}
	public void generateDeclaredElements(){
		JavaFileParser parser = snippet.getParser();
		List<JavaTypeDeclaration> typeDecls = parser.getTypeDeclarations();
		for (JavaTypeDeclaration javaTypeDeclaration : typeDecls) {
			//declared types, such as classes
			String className = javaTypeDeclaration.getName();
			if(!className.equals("ClassPlaceHolder")){
				//ClassPlaceHolder is added by CodeSnippetCompleter for adjustment
				declaredTypeNames.add(javaTypeDeclaration.getFullName());
				declaredTypeNames.add(javaTypeDeclaration.getName());
			}			
			List<JavaMethodDecl> methods = javaTypeDeclaration.getMethodDecls();
			for (JavaMethodDecl javaMethodDecl : methods) {
				//declared methods
				String name = javaMethodDecl.getname();
				if(name.startsWith("<")||name.startsWith("[")||name.equals("main")||name.equals("methodPlaceHolder")){
					//skip methods such as <init> [field init]
					continue;
				}
				declaredMethodNames.add(javaMethodDecl.getname());
			}
		}
	}
}
